"""
主题管理服务
"""
from typing import List, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, and_
from app.models.theme import Theme
from app.schemas.theme import ThemeCreate, ThemeUpdate, ThemeListResponse
from app.utils.exceptions import ThemeNotFoundError, DatabaseError
from app.utils.logger import logger
from app.utils.helpers import generate_uuid


class ThemeService:
    """主题管理服务"""
    
    async def create_theme(self, db: AsyncSession, theme_data: ThemeCreate) -> Theme:
        """创建主题"""
        try:
            theme = Theme(
                id=generate_uuid(),
                name=theme_data.name,
                description=theme_data.description,
                keywords=theme_data.keywords,
                style=theme_data.style,
                target_audience=theme_data.target_audience,
                content_length=theme_data.content_length,
                is_active=theme_data.is_active
            )
            
            db.add(theme)
            await db.commit()
            await db.refresh(theme)
            
            logger.info(f"创建主题成功: {theme.name} (ID: {theme.id})")
            return theme
            
        except Exception as e:
            await db.rollback()
            logger.error(f"创建主题失败: {str(e)}")
            raise DatabaseError(f"创建主题失败: {e}")
    
    async def get_theme_by_id(self, db: AsyncSession, theme_id: str) -> Theme:
        """根据ID获取主题"""
        try:
            result = await db.execute(select(Theme).where(Theme.id == theme_id))
            theme = result.scalar_one_or_none()
            
            if not theme:
                raise ThemeNotFoundError(theme_id)
            
            return theme
            
        except ThemeNotFoundError:
            raise
        except Exception as e:
            logger.error(f"查询主题失败: {str(e)}")
            raise DatabaseError(f"查询主题失败: {e}")
    
    async def get_themes(self, db: AsyncSession, skip: int = 0, limit: int = 20, 
                        active_only: bool = False) -> ThemeListResponse:
        """获取主题列表"""
        try:
            # 构建查询条件
            where_conditions = []
            if active_only:
                where_conditions.append(Theme.is_active == True)
            
            # 查询总数
            count_query = select(func.count(Theme.id))
            if where_conditions:
                count_query = count_query.where(and_(*where_conditions))
            
            total_result = await db.execute(count_query)
            total = total_result.scalar()
            
            # 查询主题列表
            query = select(Theme).order_by(Theme.created_at.desc())
            if where_conditions:
                query = query.where(and_(*where_conditions))
            
            query = query.offset(skip).limit(limit)
            result = await db.execute(query)
            themes = result.scalars().all()
            
            # 计算分页信息
            page = (skip // limit) + 1 if limit > 0 else 1
            has_next = (skip + len(themes)) < total
            
            logger.info(f"获取主题列表成功，共 {total} 条记录")
            
            return ThemeListResponse(
                items=themes,
                total=total,
                page=page,
                page_size=limit,
                has_next=has_next
            )
            
        except Exception as e:
            logger.error(f"获取主题列表失败: {str(e)}")
            raise DatabaseError(f"获取主题列表失败: {e}")
    
    async def update_theme(self, db: AsyncSession, theme_id: str, theme_data: ThemeUpdate) -> Theme:
        """更新主题"""
        try:
            theme = await self.get_theme_by_id(db, theme_id)
            
            # 更新字段
            update_data = theme_data.dict(exclude_unset=True)
            for field, value in update_data.items():
                setattr(theme, field, value)
            
            await db.commit()
            await db.refresh(theme)
            
            logger.info(f"更新主题成功: {theme.name} (ID: {theme.id})")
            return theme
            
        except ThemeNotFoundError:
            raise
        except Exception as e:
            await db.rollback()
            logger.error(f"更新主题失败: {str(e)}")
            raise DatabaseError(f"更新主题失败: {e}")
    
    async def delete_theme(self, db: AsyncSession, theme_id: str) -> bool:
        """删除主题"""
        try:
            theme = await self.get_theme_by_id(db, theme_id)
            
            await db.delete(theme)
            await db.commit()
            
            logger.info(f"删除主题成功: {theme.name} (ID: {theme_id})")
            return True
            
        except ThemeNotFoundError:
            raise
        except Exception as e:
            await db.rollback()
            logger.error(f"删除主题失败: {str(e)}")
            raise DatabaseError(f"删除主题失败: {e}")
    
    async def get_active_themes(self, db: AsyncSession) -> List[Theme]:
        """获取所有启用的主题"""
        try:
            result = await db.execute(
                select(Theme)
                .where(Theme.is_active == True)
                .order_by(Theme.created_at.desc())
            )
            themes = result.scalars().all()
            
            logger.info(f"获取启用主题成功，共 {len(themes)} 个")
            return themes
            
        except Exception as e:
            logger.error(f"获取启用主题失败: {str(e)}")
            raise DatabaseError(f"获取启用主题失败: {e}")
    
    async def toggle_theme_status(self, db: AsyncSession, theme_id: str) -> Theme:
        """切换主题启用状态"""
        try:
            theme = await self.get_theme_by_id(db, theme_id)
            
            theme.is_active = not theme.is_active
            await db.commit()
            await db.refresh(theme)
            
            status = "启用" if theme.is_active else "禁用"
            logger.info(f"{status}主题成功: {theme.name} (ID: {theme_id})")
            return theme
            
        except ThemeNotFoundError:
            raise
        except Exception as e:
            await db.rollback()
            logger.error(f"切换主题状态失败: {str(e)}")
            raise DatabaseError(f"切换主题状态失败: {e}")
    
    async def search_themes(self, db: AsyncSession, keyword: str, skip: int = 0, 
                           limit: int = 20) -> ThemeListResponse:
        """搜索主题"""
        try:
            # 构建搜索条件
            search_condition = Theme.name.contains(keyword)
            
            # 查询总数
            count_query = select(func.count(Theme.id)).where(search_condition)
            total_result = await db.execute(count_query)
            total = total_result.scalar()
            
            # 查询主题列表
            query = select(Theme).where(search_condition).order_by(Theme.created_at.desc())
            query = query.offset(skip).limit(limit)
            result = await db.execute(query)
            themes = result.scalars().all()
            
            # 计算分页信息
            page = (skip // limit) + 1 if limit > 0 else 1
            has_next = (skip + len(themes)) < total
            
            logger.info(f"搜索主题成功，关键词: {keyword}，共 {total} 条记录")
            
            return ThemeListResponse(
                items=themes,
                total=total,
                page=page,
                page_size=limit,
                has_next=has_next
            )
            
        except Exception as e:
            logger.error(f"搜索主题失败: {str(e)}")
            raise DatabaseError(f"搜索主题失败: {e}")


# 全局服务实例
theme_service = ThemeService()